package com.nuanshui.heatedloan.fund.biz.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.nuanshui.framework.consts.TransactionManagerType;
import com.nuanshui.framework.lang.SysStringUtils;
import com.nuanshui.framework.security.DESC;
import com.nuanshui.framework.utils.LogUtil;
import com.nuanshui.heatedloan.baseservice.facade.ImageService;
import com.nuanshui.heatedloan.baseservice.facade.OrderNumGenerate;
import com.nuanshui.heatedloan.baseservice.service.CommonServiceImpl;
import com.nuanshui.heatedloan.constant.GlobalParam;
import com.nuanshui.heatedloan.credit.facade.CustomerBankCardInfoService;
import com.nuanshui.heatedloan.credit.facade.CustomerIdCardInfoService;
import com.nuanshui.heatedloan.credit.facade.PayOrderInfoService;
import com.nuanshui.heatedloan.credit.vo.CustomerBankCardInfoVO;
import com.nuanshui.heatedloan.credit.vo.CustomerIdCardInfoVO;
import com.nuanshui.heatedloan.credit.vo.PayOrderInfoVO;
import com.nuanshui.heatedloan.dubbo.extension.DubboContextManager;
import com.nuanshui.heatedloan.fund.biz.dal.mapper.UserAccountBillMapper;
import com.nuanshui.heatedloan.fund.biz.dal.mapper.UserBindAccountMapper;
import com.nuanshui.heatedloan.fund.constant.AccountBillStatus;
import com.nuanshui.heatedloan.fund.constant.AccountBillSubType;
import com.nuanshui.heatedloan.fund.constant.AccountBillType;
import com.nuanshui.heatedloan.fund.enums.PaymentBizType;
import com.nuanshui.heatedloan.fund.enums.PlatformEnum;
import com.nuanshui.heatedloan.fund.facade.OrderNumWithPayNumService;
import com.nuanshui.heatedloan.fund.facade.UserAccountBillService;
import com.nuanshui.heatedloan.fund.facade.UserFundActionService;
import com.nuanshui.heatedloan.fund.form.UserAccountBillForm;
import com.nuanshui.heatedloan.fund.form.UserBillInfoForm;
import com.nuanshui.heatedloan.fund.model.BatchPayNum;
import com.nuanshui.heatedloan.fund.model.UserAccount;
import com.nuanshui.heatedloan.fund.model.UserAccountBill;
import com.nuanshui.heatedloan.fund.vo.UserAccountBillVO;
import com.nuanshui.heatedloan.fund.vo.UserBillInfoVO;
import com.nuanshui.heatedloan.pageable.Pager;
import com.nuanshui.heatedloan.userinfo.model.SimpleUserInfo;
import com.nuanshui.heatedloan.userinfo.tool.UserTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 此Service自身不做审核业务，也不能手动插入数据，需要分配到具体的功能去做审核
 * @author Junyan2015
 * @date 2016年2月18日 下午4:35:37
 */
@Service
@Transactional(readOnly = true,value=TransactionManagerType.FUND_TRANSACTION_MANAGER)
public class UserAccountBillServiceImpl extends CommonServiceImpl implements UserAccountBillService,InitializingBean{

	@Autowired
	private UserAccountBillMapper userAccountBillMapper;
	
	@Autowired
	private UserFundActionService userFundActionService;

	@Reference(url = GlobalParam.BASESERVICE_DUBBO_SERVER, timeout = GlobalParam.DUBBO_SERVER_TIME_OUT,version = GlobalParam.BASESERVICE_DUBBO_SERVER_VERSION)
	private OrderNumGenerate orderNumGenerate;
	
	@Autowired
	private UserBindAccountMapper userBindAccountMapper;

	@Reference(url = GlobalParam.USER_DUBBO_SERVER, timeout = GlobalParam.DUBBO_SERVER_TIME_OUT,version = GlobalParam.USER_DUBBO_SERVER_VERSION)
	private UserTool userTool;

	@Autowired
	private OrderNumWithPayNumService orderNumWithPayNumService;

	private static final Logger logger = LoggerFactory.getLogger(UserAccountBillServiceImpl.class);

	@Reference(url= GlobalParam.CREDIT_DUBBO_SERVER,timeout=GlobalParam.DUBBO_SERVER_TIME_OUT,version = GlobalParam.CREDIT_DUBBO_SERVER_VERSION)
	private PayOrderInfoService payOrderInfoService;

	@Reference(url= GlobalParam.CREDIT_DUBBO_SERVER,timeout=GlobalParam.DUBBO_SERVER_TIME_OUT,version = GlobalParam.CREDIT_DUBBO_SERVER_VERSION)
	private CustomerIdCardInfoService customerIdCardInfoService;

	@Reference(url= GlobalParam.CREDIT_DUBBO_SERVER,timeout=GlobalParam.DUBBO_SERVER_TIME_OUT,version = GlobalParam.CREDIT_DUBBO_SERVER_VERSION)
	private CustomerBankCardInfoService customerBankCardInfoService;

	@Override
	public void afterPropertiesSet() throws Exception {
		customerIdCardInfoService = DubboContextManager.getDubboBean(CustomerIdCardInfoService.class,GlobalParam.CREDIT_DUBBO_SERVER_VERSION);
		customerBankCardInfoService = DubboContextManager.getDubboBean(CustomerBankCardInfoService.class,GlobalParam.CREDIT_DUBBO_SERVER_VERSION);
	}

	@Override
	public Pager<UserBillInfoVO> loadPaylist(Pager<UserBillInfoVO> pager, UserBillInfoForm userBillInfoForm) {
		List<UserBillInfoVO> list = userAccountBillMapper.loadlist(pager,userBillInfoForm);
		for (UserBillInfoVO vo : list){
			if(SysStringUtils.isNotEmpty(vo.getMoney())){
				vo.setMoney(vo.getMoney());
			}
			PayOrderInfoVO payOrderInfoVO =payOrderInfoService.loadVOByOrderNo(vo.getOrderNum());
			if(payOrderInfoVO != null ){
				CustomerBankCardInfoVO customerBankCardInfoVO = customerBankCardInfoService.loadVOByMixCardNo(payOrderInfoVO.getMixCardNo());
				vo.setLendTime(payOrderInfoVO.getLendTime());
				vo.setBankCode(DESC.decrypt3DES(payOrderInfoVO.getMixCardNo()));
				vo.setOrderCreatedTime(payOrderInfoVO.getCreatedAt());
				vo.setOrderStatus(payOrderInfoVO.getOrderStatus());
				vo.setLoadDay(payOrderInfoVO.getLoadDays());
				vo.setBankName(customerBankCardInfoVO != null?customerBankCardInfoVO.getCardBankName():"");
				/****--------------入账特有的属性-------------------*****/
				if(Integer.parseInt(userBillInfoForm.getSubType()) == AccountBillSubType.TYPE_REPAY){
					vo.setOverdueDay(payOrderInfoVO.getOverdueDays());
					vo.setPayMent("一次性还款"); //目前只有一次性还款
					vo.setPayAmount(payOrderInfoVO.getOrderAmount()+payOrderInfoVO.getOverdueFee());
					vo.setRemaindAmount(vo.getPayAmount()-Float.parseFloat(vo.getMoney()));
					vo.setPaymentMethod(vo.getBankName());
					vo.setRepayBankCode(DESC.decrypt3DES(payOrderInfoVO.getRepayMixCardNo()));
					vo.setReturnTime(payOrderInfoVO.getReturnTime());
					vo.setLoadAmount(payOrderInfoVO.getLoanAmount());
					vo.setBaseRate(payOrderInfoVO.getBaseRate());
					vo.setBaseAmt(payOrderInfoVO.getBaseAmt());
					vo.setInterestRate(payOrderInfoVO.getInterestRate());
					vo.setInterestAmt(payOrderInfoVO.getInterestAmt());
                    vo.setOverdueFree(payOrderInfoVO.getOverdueFee());
                    vo.setOverdueManageFree(10); //逾期管理费是死的
				}
			}
			CustomerIdCardInfoVO customerIdCardInfoVO = customerIdCardInfoService.loadByUserId(vo.getUserId());
			if(customerIdCardInfoVO !=null ){
				vo.setUserName(customerIdCardInfoVO.getCustomerName());
			}

			vo.setSourceMoney("a1"); //目前不知道该来源，先写死
		}
		pager.setData(list);
		return pager;
	}

	@Override
	public Map<String,Object> loadSum(UserBillInfoForm userBillInfoForm,Map<String,Object> resultMap) {
		List<UserBillInfoVO>  list =userAccountBillMapper.loadSum(userBillInfoForm);
		int sumtMoney =0;
		for(UserBillInfoVO vo :list){
			int subSum= vo.getSubSum();
			sumtMoney += subSum;
			switch (vo.getStatus()){
				case AccountBillStatus.COMPLETE :
					  resultMap.put("successMoney",subSum);
					  break;
				case AccountBillStatus.NOPASS :
					  resultMap.put("failMoney",subSum);
					  break;
				case AccountBillStatus.AUDIT :
					resultMap.put("auditMoney",subSum);
					break;
				default:
					break;
			}
		}
		resultMap.put("sumMoney",sumtMoney);
		return resultMap;
	}

	@Override
	public Map<String,Object> loadCount(UserBillInfoForm userBillInfoForm,Map<String,Object> resultMap) {
		List<UserBillInfoVO>  list =userAccountBillMapper.loadCount(userBillInfoForm);
		for(UserBillInfoVO vo :list){
			switch (vo.getStatus()){
				case AccountBillStatus.COMPLETE :
					resultMap.put("successCount",vo.getSubCount());
					break;
				case AccountBillStatus.NOPASS :
					resultMap.put("failCount",vo.getSubCount());
					break;
				case AccountBillStatus.AUDIT :
					resultMap.put("auditCount",vo.getSubCount());
					break;
				default:
					break;
			}
		}
		return resultMap;
	}

	@Override
	public List<UserAccountBill> findUserAccountBill(Integer num, String userId, Pageable pager) {		
		List<UserAccountBill> list = null;
		if(num == 4) num = 6;
		if(num == 0) {//查询所有的
			LogUtil.info(logger, "正在查询全部账单数据...");
			list = userAccountBillMapper.findUserAccountBill(userId, pager);
		}else if(num == 1) {//充值（余额充值和虚拟币 充值）
			list = userAccountBillMapper.findUserAccountBillByTypes(Arrays.asList(PaymentBizType.RECHARGE.getCode()), userId, pager);
		}else if(num == 2) {// 提现
			list = userAccountBillMapper.findUserAccountBillByTypes(Arrays.asList(PaymentBizType.WITHDRAW_CASH.getCode()), userId, pager);
		}else {
			LogUtil.info(logger, "正在查询"+num+"类型账单数据");
			list = userAccountBillMapper.findUserAccountBillByType(num, userId, pager);
		}
		if(list == null) return new ArrayList<UserAccountBill>();
		
		for(UserAccountBill item : list) {
			this.setUserAccountBillParams(item, false); //用户获得其账单信息时需要设置的属性
		}
		
		return list;
	}

	@Override
	public UserAccountBill findBillDetail(String billId) {
		UserAccountBill result = userAccountBillMapper.findBillDetail(billId);
		this.setUserAccountBillParams(result, false);
		return result;
	}

	@Override
	public List<UserAccountBill> findAllUserAccountBill(Integer num, Pageable pager) {
		// TODO Auto-generated method stub
		LogUtil.info(logger, "正在查询第"+(num+1)+"个点击块的账单信息");
		List<UserAccountBill> list = null;
		Integer type = 0;
		if(num == 0) {
			list = userAccountBillMapper.findAllUserAccountBill(pager);
		}else if(num == 1) {
			list = userAccountBillMapper.findAllUserAccountBillInReview(pager);
		}else if(num == 2){
			type = com.nuanshui.heatedloan.constant.AccountBillType.DRAW_CASH; //提现模块
			list = userAccountBillMapper.findAllUserAccountBillByType(type, pager);
		}else if(num == 3) {
			type = com.nuanshui.heatedloan.constant.AccountBillType.MARGIN;
			list = userAccountBillMapper.findAllUserAccountBillByType(type, pager);
		}else if(num == 4) {
			list = userAccountBillMapper.findAllUserAccountBillByType(com.nuanshui.heatedloan.constant.AccountBillType.CROWD_FUNDING, pager);
		}else if(num == 5) {
			list = userAccountBillMapper.findAllUserAccountBillByTypes(Arrays.asList(7,8,16), pager);

		}else if(num == 1000){
			//收益筛选
			list = userAccountBillMapper.findAllUserAccountBillByIncome(pager);
		}else {	
			LogUtil.info(logger, "正在查询"+num+"类型账单数据");
			list = userAccountBillMapper.findAllUserAccountBillByType(num, pager);
		}
			
		
		if(list == null) return new ArrayList<UserAccountBill>();
		
		for(UserAccountBill item : list) {
			this.setUserAccountBillParams(item, true);  //管理员获得所有账单信息时需要设置的属性
		}
		
		return list;
	}

	public UserAccountBill findSuccessAccountBillByPayNum(String dealNum) {
		return userAccountBillMapper.findSuccessAccountBillByPayNum(dealNum);
	}

	@Override
	@Transactional(value=TransactionManagerType.FUND_TRANSACTION_MANAGER)
	public void updateStatusByDealNum(String dealNum, Integer status,Integer subStatus)
	{
		userAccountBillMapper.updateStatusByDealNum(dealNum,status,subStatus);
	}

	@Override
	@Transactional(value=TransactionManagerType.FUND_TRANSACTION_MANAGER)
	public boolean checkUserAction(String billId, String type, Integer isPass) {
		/**
		 * 此Service自身不做审核业务，也不能手动插入数据，需要分配到具体的功能去做审核
		 */
		if(PaymentBizType.WITHDRAW_CASH.getCode().equals(type)) {//表示审核提现
			//余额审核
			LogUtil.info(logger, "正在进行余额审核...");
			userFundActionService.checkUserCashing(null, isPass, billId);
		}else {
			//其他的type，以后有新的功能就做新的审核功能
			LogUtil.info(logger, "type传值错误!");
		}
		return true;
		
	}
	
	/**
	 * 设置账单相关信息
	 * @author Junyan2015
	 * @date 2016年2月18日 下午4:11:38
	 * @param item
	 */
	private void setUserAccountBillParams(UserAccountBill item, boolean isManager) {
		item.setPayMethod(PlatformEnum.getFullNameByName(item.getPlatform()));
		if (AccountBillType.TYPE_REFUND.equals(item.getType())) {
			if(isManager) {
				item.setActionName(item.getName());
			}else {
				item.setActionName(item.getName());
			}
			item.setPlatform("余额入账");
		}
		else if(AccountBillType.TYPE_RECHARGE.equals(item.getType())) {//充值账单
			if(isManager) {
				item.setActionName("充值余额");
			}else {
				item.setActionName("充值");
			}
			item.setPlatform(PlatformEnum.getFullNameByName(item.getPlatform()) + "支付");
		}else if(AccountBillType.TYPE_WITHDRAW_CASH.equals(item.getType())) {//提现
			if(isManager) {
				item.setActionName("提现余额");
			}else {
				item.setActionName("提现");
			}
			item.setPlatform(PlatformEnum.getFullNameByName(item.getPlatform()) + "转账");
		} else if (AccountBillType.TYPE_LOAN_SINGLE.equals(item.getType())){//展馆付费预约
			if(isManager) {
				item.setActionName(item.getName());
			}else {
				item.setActionName(item.getName());
			}
			item.setOrderNumber(orderNumWithPayNumService.loadByPayNum(item.getDealNum()).getOrderNum());
			item.setPlatform(PlatformEnum.getFullNameByName(item.getPlatform()) + "支付");
		} else if (AccountBillType.TYPE_LOAN_LIGHT.equals(item.getType())){//活动付费预约
			if(isManager) {
				item.setActionName(item.getName());
			}else {
				item.setActionName(item.getName());
			}
			item.setOrderNumber(orderNumWithPayNumService.loadByPayNum(item.getDealNum()).getOrderNum());
			item.setPlatform(PlatformEnum.getFullNameByName(item.getPlatform()) + "支付");
		}else if (AccountBillType.TYPE_LOAN_INSTALLMENT.equals(item.getType())){//电影付费预约
			if(isManager) {
				item.setActionName(item.getName());
			}else {
				item.setActionName(item.getName());
			}
			item.setOrderNumber(orderNumWithPayNumService.loadByPayNum(item.getDealNum()).getOrderNum());
			item.setPlatform(PlatformEnum.getFullNameByName(item.getPlatform()) + "支付");
		}
	}

	@Override
	@Transactional(value=TransactionManagerType.FUND_TRANSACTION_MANAGER)
	public   UserAccountBill  insertBillRecord(UserAccountBill userAccountBill) {
		if(SysStringUtils.isEmpty(userAccountBill.getDealNum())) {
			String dealNum = orderNumGenerate.getDealNum(userAccountBill.getBillBizType());
			userAccountBill.setDealNum(dealNum);
		}
		
		userAccountBillMapper.insertBillRecord(userAccountBill);
		return userAccountBill;
		
		
	}

	@Override
	public UserAccountBill findBillDetailByDealNum(String dealNum) {
		
		return userAccountBillMapper.loadByDealNum(dealNum);
	}

	@Override
	public Long findMaxDealNumByDay(String day, String bizType) {
		return userAccountBillMapper.findMaxDealNumByDay(day, bizType);
	}

	@Override
	public void insertDealNum(String day, String bizType) {
		userAccountBillMapper.insertDealNum(day, bizType);
		
	}

	@Override
	public void incrDealNumByDay(String day, String bizType) {
		userAccountBillMapper.incrDealNumByDay(day, bizType);
	}
	@Override
	public List<BatchPayNum> findBatchPayNumsByPayNum(String payNum){
		return userAccountBillMapper.findBatchPayNumsByPayNum(payNum);
	}
	
	@Override
	public List<BatchPayNum> findSuccessBatchPayNumsByPayNum(String payNum){
		return userAccountBillMapper.findSuccessBatchPayNumsByPayNum(payNum);
	}
	
	@Override
	public String findUserNotEndedBatchPayNum(String userId){
		return userAccountBillMapper.findUserNotEndedBatchPayNum(userId);
	}

	@Override
	@Transactional(value=TransactionManagerType.FUND_TRANSACTION_MANAGER)
	public void updateBatchPayNumStatus(BatchPayNum batchPayNum) {
		userAccountBillMapper.updateBatchPayNumStatus(batchPayNum);
	}
	
	@Override
	public Integer findBatchPayCountByPayNum(String payNum){
		return userAccountBillMapper.findBatchPayCountByPayNum(payNum);
	}

	@Override
	public Integer findBatchPaySuccessOrCancelCountByPayNum(String payNum) {
		return userAccountBillMapper.findBatchPaySuccessOrCancelCountByPayNum(payNum);
	}

	@Override
	public Pager<UserAccountBillVO> list(Pager<UserAccountBillVO> pager,UserAccountBillForm uabf) {
		return pager;
	}

	@Override
	public String getDes(String dn) {
		return userAccountBillMapper.getDes(dn);
	}

	@Override
	@Transactional(readOnly = false,value=TransactionManagerType.FUND_TRANSACTION_MANAGER)
	public void modifyDes(String newDes, String dealNum) {
		userAccountBillMapper.modifyDes(newDes, dealNum);
	}

	@Override
	public UserAccountBill getAccountMessage(String dn) {
		UserAccountBill userAccountBill = userAccountBillMapper.loadByDealNum(dn);
		userAccountBill.setPlatform(PlatformEnum.getFullNameByName(userAccountBill.getPlatform()));
		SimpleUserInfo user = userTool.getSimpleUserInfo(userAccountBill.getUserId());
		userAccountBill.setPhoneNumber(user.getPhone());
		UserAccount userAccount = userBindAccountMapper.loadPayAccountByUserId(userAccountBill.getUserId());
		userAccountBill.setUserName(userAccount.getRealName());
		userAccountBill.setAccountNum(userAccount.getAccount());
		return userAccountBill;
	}

}

